<?php

namespace catchAdmin\stock\controller;

use catchAdmin\stock\model\Stock;
use catchAdmin\stock\model\WarehouseConfig;
use catchAdmin\storehouse\controller\InventoryOperationRecord;
use catchAdmin\storehouse\model\Warehousing;
use catcher\base\CatchRequest as Request;
use catcher\CatchResponse;
use catcher\base\CatchController;
use catchAdmin\stock\model\Pick as PickModel;
use think\Exception;
use think\Response;
use catcher\CatchAuth;
use think\facade\Db;

class Pick extends CatchController
{

    protected $pickModel;

    /**
     *
     * @time 2022/01/26 17:31
     * @param PickModel $pickModel
     * @return mixed
     */
    public function __construct(PickModel $pickModel)
    {
        $this->pickModel = $pickModel;
    }

    /**
     * 拣货列表
     * @time 2022/01/26 17:31
     * @param Request $request
     */
    public function index(CatchAuth $auth, Request $request)
    {
        $user = $auth->user();
        $params = $request->post();

        //委托方在仓库里商品的条件
        $where1 = [];
        $where1[] = ['s.warehouse_out_son_id', '=', $params['warehouse_out_son_id']];
        $where1[] = ['s.deleted_at', '=', 0];
        $where1[] = ['o.deleted_at', '=', 0];
        $where1[] = ['s.tenant_id', '=', $user['tenant_id']];
        $where1[] = ['o.tenant_id', '=', $user['tenant_id']];
        $out_son = Db::name('db_warehouse_out_son')
            ->alias('s')
            ->join('db_warehouse_out o', 's.warehouse_out_id = o.warehouse_out_id')
            ->field('o.project_client,s.*')
            ->where($where1)
            ->find();
        //仓库
        $where = [];
        //搜索条件
        if (!empty($params['tray_id'])) {
            $where[] = ['s.tray_id', '=', $params['tray_id']];
        }
        if (!empty($params['batch_number'])) {
            $where[] = ['s.batch_number', '=', $params['batch_number']];
        }
        if (!empty($params['number'])) {
            $where[] = ['s.Good_Qty', '=', $params['number']];
        }
        if (!empty($params['config_name'])) {
            $config_id = Db::table('db_warehouse_config')->where('name', $params['config_name'])->value('config_id');
            $where[] = ['s.config_id', '=', $config_id];
        }
//        if(array_key_exists('tray_id',$params) === true){
//            $where[] = ['s.tray_id','=',$params['tray_id']];
//        }
//        if(array_key_exists('batch_number',$params) === true){
//            $where[] = ['s.batch_number','=',$params['batch_number']];
//        }
//        //搜索数量，取Good_Qty字段
//        if(array_key_exists('number',$params) === true){
//            $where[] = ['s.Good_Qty','=',$params['number']];
//        }
//        if(array_key_exists('config_name',$params) === true){
//            $config_id=Db::table('db_warehouse_config')->where('name',$params['config_name'])->value('config_id');
//            $where[] = ['s.config_id','=',$config_id];
//        }
        $where[] = ['s.project_client', '=', $out_son['project_client']];
        $where[] = ['s.goods_id', '=', $out_son['goods_id']];
        $where[] = ['s.packing_id', '=', $out_son['packing_id']];
        $where[] = ['ws.deleted_at', '=', 0];
        $where[] = ['w.deleted_at', '=', 0];
        $where[] = ['s.tenant_id', '=', $user['tenant_id']];
        $where[] = ['s.status', '<>', 1];
//        $where[] = ['s.Good_Qty','>',0];

        //出库筛选
        if (!empty($out_son['conditions_warehousing_no'])) {
            $where[] = ['s.warehousing_id', 'in', explode(',', $out_son['conditions_warehousing_no'])];
        }

        //业务单号筛选
        if (array_key_exists('customer_business_number', $params)) {//前台搜索
            $warehousing_ids = (new Warehousing)->where('customer_business_number', $params['customer_business_number'])->column('warehousing_id');
            $where[] = ['s.warehousing_id', 'in', $warehousing_ids];
        }

        //入库日期
        if (array_key_exists('created_at', $params) && !empty($params['created_at'])) {//前台搜
            $start = strtotime($params['created_at'][0]);
            $end = strtotime($params['created_at'][1]);
            $where[] = ['s.created_at', 'between', [$start, $end]];
        }

        $stock = DB::name('db_stock')
            ->alias('s')
//                    ->leftJoin('db_box b','s.tray_id = b.tray_id and b.status <> "1"')
//                    ->leftJoin('db_slice sl','b.box_id = sl.box_id and sl.status = "0"')
            ->leftJoin('db_warehousing_son ws', 'ws.warehousing_son_id = s.warehousing_son_id')
            ->leftJoin('db_warehousing w', 'w.warehousing_id = s.warehousing_id')
            ->field('s.tray_id,
                    s.goods_name,
                    s.number,
                    s.Good_Qty,
                    s.Hold_Qty,
                    s.NG_Qty,
                    s.warehousing_id,
                    s.warehousing_son_id,
                    s.config_id,
                    s.created_at,
                    s.packing_num,
                    s.unit_name,
                    s.box_id,
                    s.slice_id,
                    w.customer_business_number,
                    s.id as stock_pid,
                    s.stock_id as stock_stock_id,
                    s.LOT1,
                    s.LOT2,
                    s.LOT3,
                    ws.batch_number')
            ->where($where)
            ->order('s.created_at', 'asc')
            ->select()
            ->toArray();
        //拣货
        $pick = DB::name('db_pick')->field('stock_id,id,tray_id,box_id,slice_id,number,warehouse_out_son_id,status,sn')->where('status', '<>', '1')->where('deleted_at', 0)->select();
        //库位
        $config = DB::name('db_warehouse_config')->where('deleted_at', 0)->field('config_id,name')->select();

        $pickTemp = [];

        foreach ($stock as $key => &$value) {
            $sn = [];
            $stock[$key]['id'] = 0;
            $stock[$key]['created_at'] = date("Y-m-d H:i", $value['created_at']);

//            $stock[$key]['number'] = '';
            $stock[$key]['locking'] = 0;
            //处理箱号，片号 为0情况
            if (empty($value['box_id'])) {
                $value['box_id'] = '';
            }
            if (empty($value['slice_id'])) {
                $value['slice_id'] = '';
            }

            //找出锁定的货品

            //自己a 200
            //b 300
            //c 200
            //d 0

            //a 锁定就是 500 捡货就是 200
            //b 锁定就是 400 贱货就是 300
            //c 锁定就是 500 贱货就是 200
            //d 锁定就是1400 捡获 0

            $value['_self_pick_num'] = 0;//初始捡获数量肯定是0
            $value['_locking_num'] = 0;//锁定也是0

            $stockTBS = $value['stock_stock_id'] . $value['tray_id'] . $value['box_id'] . $value['slice_id'];

            foreach ($pick as $k => $v) {
                //处理捡获，箱号，片号 为0情况
                if (empty($v['box_id'])) {
                    $v['box_id'] = '';
                }
                if (empty($v['slice_id'])) {
                    $v['slice_id'] = '';
                }
                $pickTBS = $v['stock_id'] . $v['tray_id'] . $v['box_id'] . $v['slice_id'];

                if (array_key_exists($pickTBS, $pickTemp)) {
                    $pickTemp[$pickTBS][$v['warehouse_out_son_id']] = $v;
                } else {
                    $pickTemp[$pickTBS] = [$v['warehouse_out_son_id'] => $v];
                }

                //1.捡货数量是自己锁定的数量

                //2.锁定数量是除了自己，其他所有订单锁定的数量（不能包含自己）
                if ($stockTBS == $pickTBS) {//有捡货锁定的。

                    if (array_key_exists($params['warehouse_out_son_id'], $pickTemp[$pickTBS])) {

//                        $value['_self_pick_num'] += (int)$pickTemp[$pickTBS][$params['warehouse_out_son_id']]['number'];
//
//                        $value['_locking_num'] = array_sum(array_column($pickTemp[$pickTBS], 'number')) - $value['_self_pick_num'];
                        $value['_self_pick_num'] += (int)$pickTemp[$pickTBS][$params['warehouse_out_son_id']]['number'];

                        $value['_locking_num'] = 0;
                    } else {
                        $value['_locking_num'] = array_sum(array_column($pickTemp[$pickTBS], 'number'));
                    }
                    $sn[] = $v['sn'];
                }

            }

            foreach ($config as $k1 => $v1) {
                if ($stock[$key]['config_id'] === $v1['config_id']) {
                    $stock[$key]['config_name'] = $v1['name'];
                }
            }
            if (!empty($sn)) {
                //$value['sn'] = implode(',', $sn);
                $value['sn'] = '';
            }
        }

        $pick_locking_all_num = array_sum(array_column($stock, '_self_pick_num'));

//        dd($pick_sy_temp);

        //处理移动的库存，不能捡货
        $move_loading_result_ids = Db::table('db_move')->where([
            ['tenant_id', '=', $user->tenant_id],
            ['status', '=', 0],
            ['deleted_at', '=', 0]
        ])->column('stock_id');

        //查看该捡货单，已经出库数量
        $pick_out_num = (int)Db::table('db_pick')
            ->where('warehouse_out_son_id', $params['warehouse_out_son_id'])
            ->where('deleted_at', 0)
            ->where('status', '1')
            ->sum('number');

        //$pick_sy_temp = $out_son['number'] - $pick_locking_all_num;
        //总数量 - 已经锁定的数量 - 已经出库数量
        $pick_sy_temp = $out_son['number'] - $pick_locking_all_num - $pick_out_num;


        //移库中，禁用处理
        foreach ($stock as $key => &$value) {
            if (in_array($value['stock_stock_id'], $move_loading_result_ids)) {
                $value['disabled'] = 'disabled';
            }
        }

        //自动分配
        foreach ($stock as $key => &$value) {
            //移库中，就不要在分配了，直接跳过
            if (array_key_exists('disabled', $value) && 'disabled' == $value['disabled']) {
                continue;
            }

            //不是Good的也直接跳过
            if ($value['Good_Qty'] <= 0) {
                continue;
            }
            // 正常分配没有歧义的库存
            if (0 == $value['_self_pick_num']) {//没有的话，那就分配，分配的数量要去除被别人锁定的数量
                $max_generate_pick_num = array_key_exists('_locking_num', $value)
                    ? $value['Good_Qty'] - $value['_locking_num']
                    : $value['Good_Qty'];

                unset($value['_self_pick_num']);
                //打个补丁：type=1为手动拣货_generate_pick_num归0
                if (!empty($params['type']) && $params['type'] == 1) {
                    $value['_generate_pick_num'] = 0;
                } else {
                    if ($pick_sy_temp < $max_generate_pick_num) {//剩余的有点少
                        $value['_generate_pick_num'] = $pick_sy_temp;
                        break;
                    } else {
                        $value['_generate_pick_num'] = $max_generate_pick_num;
                    }
                    $pick_sy_temp -= $value['_generate_pick_num'];
                }
            }
        }

        $stock = array_values($stock);
//        return CatchResponse::success($stock, '查询成功');

        $out_son_result = $out_son;
        $out_son_result['_generate_all_counts'] = array_sum(array_column($stock, '_generate_pick_num'));
        $out_son_result['_self_all_counts'] = array_sum(array_column($stock, '_self_pick_num'));
        $out_son_result['_pick_out_num'] = $pick_out_num;

        return CatchResponse::success(['stock' => $stock, 'out_son' => $out_son_result], '查询成功');
    }

    /**
     * 快速出库列表
     * @time 2022/01/26 17:31
     * @param Request $request
     * @return Response
     */
    public function fast(CatchAuth $auth, Request $request): Response
    {
        $user = $auth->user();
        $params = $request->filterEmptyField()->post();

        //委托方在仓库里商品的条件
        $where1 = [];
        $where1[] = ['warehouse_out_id', '=', $params['warehouse_out_id']];
        $where1[] = ['deleted_at', '=', 0];
        $where1[] = ['tenant_id', '=', $user['tenant_id']];
        $project_client = Db::name('db_warehouse_out')
            ->where($where1)
            ->value('project_client');
        $out_son = ['project_client' => $project_client];
        $out_son['goods_id'] = Db::table('db_product')->where('goods_name', $params['goods_name'])->value('goods_id');
        $out_son['packing_id'] = $params['packing_id'];
        //仓库
        $where = [];
        //搜索条件
        if (array_key_exists('tray_id', $params) === true) {
            $where[] = ['s.tray_id', '=', $params['tray_id']];
        }
        if (array_key_exists('batch_number', $params) === true) {
            $where[] = ['s.batch_number', '=', $params['batch_number']];
        }
        if (array_key_exists('config_name', $params) === true) {
            $config_id = Db::table('db_warehouse_config')->where('name', $params['config_name'])->value('config_id');
            $where[] = ['s.config_id', '=', $config_id];
        }
        $where[] = ['s.project_client', '=', $out_son['project_client']];
        $where[] = ['s.goods_id', '=', $out_son['goods_id']];
        $where[] = ['s.packing_id', '=', $out_son['packing_id']];
        $where[] = ['ws.deleted_at', '=', 0];
        $where[] = ['w.deleted_at', '=', 0];
        $where[] = ['s.tenant_id', '=', $user['tenant_id']];
        $where[] = ['s.status', '<>', 1];

        $stock = DB::name('db_stock')
            ->alias('s')
            ->leftJoin('db_box b', 's.tray_id = b.tray_id and b.status <> "1"')
            ->leftJoin('db_slice sl', 'b.box_id = sl.box_id and sl.status = "0"')
            ->leftJoin('db_warehousing_son ws', 'ws.warehousing_son_id = s.warehousing_son_id')
            ->leftJoin('db_warehousing w', 'w.warehousing_id = s.warehousing_id')
            ->field('
                    s.box_number,
                    s.stock_id,
                    s.tray_id,
                    s.goods_name,
                    s.Good_Qty,
                    s.warehousing_id,
                    s.warehousing_son_id,
                    s.config_id,
                    s.created_at,
                    s.packing_num,
                    s.unit_name,
                    b.box_id,
                    b.Good_Qty as Good_Qty2,
                    b.config_id as config_id2,
                    sl.slice_id,
                    sl.number as Good_Qty3,
                    sl.config_id as config_id3,
                    w.customer_business_number,
                    ws.batch_number')
            ->where($where)
            ->order('s.created_at', 'asc')
            ->select()
            ->toArray();
        //拣货
        $pick = DB::name('db_pick')->field('id,tray_id,box_id,slice_id,number,warehouse_out_son_id,status')->where('status', '<>', '1')->where('deleted_at', 0)->select();
        //库位
        $config = DB::name('db_warehouse_config')->where('deleted_at', 0)->field('config_id,name')->select();

        foreach ($stock as $key => $value) {
            $stock[$key]['id'] = 0;
            $stock[$key]['created_at'] = date("Y-m-d H:i", $value['created_at']);
            if (!empty($value['tray_id']) && !empty($value['box_id']) && empty($value['slice_id'])) {
                //表示拆托没有拆箱
                $stock[$key]['Good_Qty'] = $stock[$key]['Good_Qty2'];
                $stock[$key]['config_id'] = $stock[$key]['config_id2'];

            } elseif (!empty($value['tray_id']) && !empty($value['box_id']) && !empty($value['slice_id'])) {
                //表示拆托拆箱成片
                $stock[$key]['Good_Qty'] = $stock[$key]['Good_Qty3'];
                $stock[$key]['config_id'] = $stock[$key]['config_id3'];
            }

            unset($stock[$key]['Good_Qty2']);
            unset($stock[$key]['Good_Qty3']);
            unset($stock[$key]['config_id2']);
            unset($stock[$key]['config_id3']);

            $stock[$key]['number'] = '';
            $stock[$key]['locking'] = 0;

            //找出锁定的货品
            foreach ($pick as $k => $v) {
                if (!empty($v['tray_id']) && empty($v['box_id']) && empty($v['slice_id'])) {
                    //没有拆托
                    if ($v['tray_id'] === $value['tray_id']) {
                        if ($params['warehouse_out_son_id'] === $v['warehouse_out_son_id']) {
                            $stock[$key]['number'] = $v['number'];
                            $stock[$key]['id'] = $v['id'];
                        } else {
                            $stock[$key]['locking'] = $v['number'];
                        }
                        $stock[$key]['status'] = $v['status'];
                    }
                } elseif (!empty($v['tray_id']) && !empty($v['box_id']) && empty($v['slice_id'])) {
                    //拆托成箱
                    if ($v['tray_id'] === $value['tray_id'] && $v['box_id'] === $value['box_id']) {
                        if ($params['warehouse_out_son_id'] === $v['warehouse_out_son_id']) {
                            $stock[$key]['number'] = $v['number'];
                            $stock[$key]['id'] = $v['id'];
                        } else {
                            $stock[$key]['locking'] = $v['number'];
                        }
                        $stock[$key]['status'] = $v['status'];
                    }
                } elseif (!empty($v['tray_id']) && !empty($v['box_id']) && !empty($v['slice_id'])) {
                    //拆托成箱,拆箱成片
                    if ($v['tray_id'] === $value['tray_id'] && $v['box_id'] === $value['box_id'] && $v['slice_id'] === $value['slice_id']) {
                        if ($params['warehouse_out_son_id'] === $v['warehouse_out_son_id']) {
                            $stock[$key]['number'] = $v['number'];
                            $stock[$key]['id'] = $v['id'];
                        } else {
                            $stock[$key]['locking'] = $v['number'];
                        }
                        $stock[$key]['status'] = $v['status'];
                    }
                }
            }

            foreach ($config as $k1 => $v1) {
                if ($stock[$key]['config_id'] === $v1['config_id']) {
                    $stock[$key]['config_name'] = $v1['name'];
                }
            }
        }

        return CatchResponse::success($stock, '查询成功');
    }

    /**
     * 拣货详情
     * @time 2022/01/26 17:31
     * @param Request $request
     * @return Response
     */
    public function indexlist(Request $request)
    {
        $params = $request->param();
        $where = [];

        if (array_key_exists('warehouse_out_son_id', $params) && !empty($params['warehouse_out_son_id'])) {
            $where[] = ['p.warehouse_out_son_id', '=', $params['warehouse_out_son_id']];
        }

        if (array_key_exists('warehouse_out_id', $params) && !empty($params['warehouse_out_id'])) {
            $where[] = ['p.warehouse_out_id', '=', $params['warehouse_out_id']];
        }

        if (array_key_exists('arbitrary_code', $params) && !empty($params['arbitrary_code'])) {
            $where[] = ['p.tray_id|p.box_id|p.slice_id|ws.goods_name|p.sn', 'like', "%{$params['arbitrary_code']}%"];
        }

//        $where[] = ['p.status','=','1'];
        $where[] = ['p.deleted_at', '=', 0];

        $list = DB::name('db_pick')
            ->alias('p')
            ->leftJoin('db_warehouse_out_son ws', 'p.warehouse_out_son_id=ws.warehouse_out_son_id')
//                    ->leftJoin('db_stock s','p.tray_id = s.tray_id')
//                    ->leftJoin('db_box b','p.box_id = b.box_id')
//                    ->leftJoin('db_slice sl','p.slice_id = sl.slice_id')
//                    ->leftJoin('db_warehousing_son ws','ws.warehousing_son_id = s.warehousing_son_id')
//                    ->leftJoin('db_warehousing w','w.warehousing_id = s.warehousing_id')
            ->field('p.tray_id,
                    p.warehouse_out_son_id,
                    p.box_id,
                    p.slice_id,
                    p.id,
                    p.stock_status,
                    ws.goods_name,
                    ws.packing_num,
                    ws.unit_name,
                    p.status,
                    p.config_id,
                    p.LOT1,
                    p.LOT2,
                    p.LOT3,
                    p.sn,
                    p.number')
//            ->field('s.tray_id,
//                    p.warehouse_out_son_id,
//                    s.goods_name,
//                    s.warehousing_id,
//                    s.warehousing_son_id,
//                    s.config_id,
//                    s.created_at,
//                    s.packing_num,
//                    s.unit_name,
//                    b.box_id,
//                    b.config_id as config_id2,
//                    sl.slice_id,
//                    sl.config_id as config_id3,
//                    w.customer_business_number,
//                    ws.batch_number,
//                    p.number')
            ->where($where)
//                    ->order('p.id', 'desc')
            ->order('p.id', 'asc')
            ->select()
            ->toArray();
//            $config = DB::name('db_warehouse_config')->field('config_id,name')->select();
        foreach ($list as $key => &$value) {

            if (!empty($value['config_id'])) {
                $config_id = $value['config_id'];
            } else {
                $config_id = Db::table('db_tray')->where('tray_id', $value['tray_id'])->value('config_id');
            }

            $list[$key]['config_name'] = Db::table('db_warehouse_config')->where('config_id', $config_id)->value('name');


            try {
                $value['config_full_name'] = (new WarehouseConfig)->where('config_id', $config_id)->find()->full_name;

            } catch (\Exception $exception) {
                throw new Exception(json_encode($value));
            }

            // $value['config_full_name'] = (new WarehouseConfig)->where('config_id',$config_id)->find()->full_name;
//                if(!empty($value['tray_id']) && !empty($value['box_id']) && empty($value['slice_id'])){
//                    $list[$key]['config_id'] = $list[$key]['config_id2'];
//
//                }elseif(!empty($value['tray_id']) && !empty($value['box_id']) && !empty($value['slice_id'])){
//                    $list[$key]['config_id'] = $list[$key]['config_id3'];
//                }

//                unset($list[$key]['config_id2']);
//                unset($list[$key]['config_id3']);

//                foreach ($config as $k1 => $v1) {
//                    if($list[$key]['config_id'] == $v1['config_id']){
//                        $list[$key]['config_name'] = $v1['name'];
//                    }
//                }
        }
        return CatchResponse::success($list, '查询成功');
    }

    public function wholeOut(CatchAuth $auth, Request $request)
    {
        $params = $request->post();
        $user = $auth->user();
        $ids = $params['ids'];
        $out_son_id = $params['warehouse_out_son_id'];

        $pick = DB::name('db_pick')
            ->where('id', 'in', $ids)
            ->where('status', '0')
            ->select()->toArray();
        $sn = [];
        if (empty($pick)) {
            return CatchResponse::fail('没有待出库的捡货库存！！！');
        }

        Db::startTrans();
        try {

            foreach ($pick as $key => $value) {
                //改
                if ($value['box_id']) {
                    $sn[] = $value['box_id'];
                }
                $stock_pick = (new Stock)->where('stock_id', $value['stock_id'])->find();

                $stock_save_data = [];
                $stock_save_data['out_number'] = $stock_pick->out_number + $value['number'];//出库数量

                //判断出库的类型 Good Hold Ng
                if ($stock_pick->Good_Qty > 0) {//Good
                    $stock_save_data['Good_Qty'] = $stock_pick->Good_Qty - $value['number'];//好的数量
                    //库存状态
                    $stock_save_data['status'] = $stock_save_data['Good_Qty'] == 0 ? 1 : 2;
                } elseif ($stock_pick->Hold_Qty > 0) {
                    $stock_save_data['Hold_Qty'] = $stock_pick->Hold_Qty - $value['number'];//hold数量
                    //库存状态
                    $stock_save_data['status'] = $stock_save_data['Hold_Qty'] == 0 ? 1 : 2;
                } elseif ($stock_pick->NG_Qty > 0) {
                    $stock_save_data['NG_Qty'] = $stock_pick->NG_Qty - $value['number'];//ng数量
                    //库存状态
                    $stock_save_data['status'] = $stock_save_data['NG_Qty'] == 0 ? 1 : 2;
                }

//                //库存状态
//                if(0 == $stock_save_data['Good_Qty'] ){//代表出完
//                    $stock_save_data['status'] = 1;//全部出库
//                }else{
//                    $stock_save_data['status'] = 2;//部分出库
//                }

                //托盘数据
                $insert_tray_data_temp = [];

                $insert_tray_data_temp['batch_number'] = $stock_pick->batch_number;
                $insert_tray_data_temp['type'] = 1;
                $insert_tray_data_temp['warehousing_id'] = $value['warehouse_out_id'];
                $insert_tray_data_temp['warehousing_son_id'] = $value['warehouse_out_son_id'];
                $insert_tray_data_temp['tenant_id'] = $user['tenant_id'];
                $insert_tray_data_temp['creator_id'] = $user['id'];
                $insert_tray_data_temp['goods_status'] = 'Good';
                $insert_tray_data_temp['status'] = 3;
                $insert_tray_data_temp['created_at'] = time();
                $insert_tray_data_temp['updated_at'] = time();
                $insert_tray_data_temp['number'] = $value['number'];
                $insert_tray_data_temp['box_number'] = ceil($value['number'] / $stock_pick->packing_num);
                $insert_tray_data_temp['tray_id'] = $value['tray_id'];
                $insert_tray_data_temp['config_id'] = $stock_pick->config_id;

                //修改库存表数据
                $stock_pick->save($stock_save_data);

                //托盘数据
                $insert_tray_data[] = $insert_tray_data_temp;

                //出库明细表修改
                //出库明细表修改
                DB::name('db_warehouse_out_son')->where('warehouse_out_son_id', $value['warehouse_out_son_id'])->inc('out_number', $value['number'])->update();


                //添加库存操作记录--start
                $inventoryOperationRecordModel = new \catchAdmin\storehouse\model\InventoryOperationRecord();

                $recordMergeData = array_merge($value, [
                    'warehousing_id' => $stock_pick['warehousing_id'],
                    'warehousing_son_id' => $stock_pick['warehousing_son_id']
                ]);
                $recordResult = (new InventoryOperationRecord($inventoryOperationRecordModel))->write(InventoryOperationRecord::ORDER_TYPE_CK, $value['warehouse_out_son_id'], $recordMergeData);
                if (!$recordResult) {
                    Db::rollback();
                    throw new Exception('[出库]库存操作记录创建失败');
                }
                //添加库存操作记录--end

            }

            //插入托盘表
            Db::table('db_tray')->insertAll($insert_tray_data);

            //出库明细表状态
            $info = DB::name('db_warehouse_out_son')
                ->field('id,number,out_number,warehouse_out_id,warehouse_out_son_id,back_sn')
                ->whereIn('warehouse_out_son_id', [$out_son_id])
                ->select()
                ->toArray();

            foreach ($info as $key => $value) {
                if ($value['number'] === $value['out_number']) {
                    //全部出库
                    $status = 1;
                } elseif (($value['out_number'] !== 0) && ($value['number'] > $value['out_number'])) {
                    //部分出库
                    $status = 2;
                }
                //改
                if ($out_son_id == $value['warehouse_out_son_id']) {
                    if (count($sn) > 0) {
                        if (empty($value['back_sn'])) {
                            $back_sn = implode(',', $sn);
                        } else {
                            $back_sn = $value['back_sn'] . ',' . implode(',', $sn);
                        }
                    } else {
                        $back_sn = '';
                    }
                }
                $a = DB::name('db_warehouse_out_son')->where('id', $value['id'])->update(['back_sn' => $back_sn, 'status' => $status, 'updated_at' => time()]);

            }

            $warehouse_out_id = Db::table('db_warehouse_out_son')->where('warehouse_out_son_id', $out_son_id)->value('warehouse_out_id');

//            //出库表状态
//            $map=[];
//            $map[]=['warehouse_out_id','=',$warehouse_out_id];
//            $map[]=['deleted_at','=',0];
//            $out = DB::name('db_warehouse_out_son')->where($map)->column('status');
//
//
//            $out_son_status = array_unique($out);//出库子订单，状态
//            if(in_array(0,$out_son_status) || in_array(2,$out_son_status)){//部分出库
//                $status = 2;
//            }else{
//                $status = 1;
//            }
//
//            DB::name('db_warehouse_out')
//                ->where('warehouse_out_id',$warehouse_out_id)
//                ->update(['status'=>$status,'updated_at'=>time()]);

            //入库主单更改状态------start
            $warehouse_out_son_all_number = Db::table('db_warehouse_out_son')
                ->where('warehouse_out_id', $warehouse_out_id)
                ->where('deleted_at', 0)
//                ->where('status',1)
                ->where('status', '<>', 0)
                ->sum('out_number');

            $warehouse_out_number = Db::table('db_warehouse_out')->where('warehouse_out_id', $warehouse_out_id)->value('goods_number');

            if ($warehouse_out_son_all_number == $warehouse_out_number) {
                $data = [];
                $data['actual_number'] = $warehouse_out_son_all_number;
                $data['status'] = 1;
                $data['updated_at'] = time();
                Db::table('db_warehouse_out')->where('warehouse_out_id', $warehouse_out_id)->update($data);
            } else if ($warehouse_out_son_all_number > 0 && $warehouse_out_son_all_number < $warehouse_out_number) {
                $data = [];
                $data['actual_number'] = $warehouse_out_son_all_number;
                $data['status'] = 2;
                $data['updated_at'] = time();
                Db::table('db_warehouse_out')->where('warehouse_out_id', $warehouse_out_id)->update($data);
            }else{
                //入库主单更改状态------end
                $outInfo =Db::table('db_warehouse_out_son')
                    ->where('warehouse_out_id', $warehouse_out_id)
                    ->where([
                        'deleted_at'=> 0,
                    ])->where('status', '<>', 1)
                    ->find();
                if(empty($outInfo)){
                    $data = [];
                    $data['actual_number'] = $warehouse_out_number;
                    $data['status'] = 1;
                    $data['updated_at'] = time();
                    Db::table('db_warehouse_out')->where('warehouse_out_id', $warehouse_out_id)->update($data);
                }
            }

            //拣货表
            DB::name('db_pick')
                ->where('id', 'in', $ids)
                ->where('status', '0')
                ->update(['status' => 1, 'updated_at' => time(), 'auth_id' => $request->user()->id]);
            Db::commit();
            return CatchResponse::success('', 'success');
        } catch (\Exception $exception) {

            Db::rollback();
            return CatchResponse::fail('失败');
            dd($exception->getTrace());
            return CatchResponse::fail('faild' . $exception->getTrace());
        }

    }


    /**
     *
     * @time 2022/01/26 17:31
     * @param Request $request
     */
    public function create(CatchAuth $auth, Request $request)
    {

        $user = $auth->user();
        $params = $request->filterEmptyField()->post();

        if (!array_key_exists('info', $params)) {
            return CatchResponse::fail('请填写拣货数量，否则无法锁定');
        }
        $sonInfo = DB::name('db_warehouse_out_son')
            ->where('warehouse_out_son_id', $params['warehouse_out_son_id'])
            ->where('deleted_at', 0)
            ->find();
        $number = $sonInfo['number'];
        $num = array_sum(array_column($params['info'], 'number'));
        if ($num > $number) {
            return CatchResponse::fail('拣货数量大于要求出库数量，请核对拣货数量');
        }
        Db::startTrans();
        try {
            $old_pick = Db::table('db_pick')->field('pick_no')->where('warehouse_out_id', $params['warehouse_out_id'])->find();
            if (!empty($old_pick)) {//有的话还用之前的单子。
                $pick_no = $old_pick['pick_no'];
            } else {
                //查询当月捡货数量
                $this_month_count = Db::table('db_pick')->where('tenant_id', $user['tenant_id'])->where('pick_no', '<>', '')
                    ->whereMonth('created_at')->column('pick_no');
                $this_month_count = count(array_unique($this_month_count));
                $co_code = Db::table('users')->where('id', $user['tenant_id'])->value('co_code');
                if ($co_code) {
                    $head = strtoupper($co_code) . "PL";
                } else {
                    $head = "CIPL";
                }
                $pick_no = $head . date("ym") . str_pad($this_month_count + 1, 5, '0', STR_PAD_LEFT);
            }
            $stockInfo = Db::table('db_stock')->where([
                'tenant_id' => $user['tenant_id'],
                'deleted_at' => 0,
                'goods_id' => $sonInfo['goods_id'],
            ])->where(function ($query)use($params,$user,$sonInfo){
                $sn = $params['info'][0]['sn'];
                $snArray = explode(',',$sn);
                if (!empty($snArray)) {
                    $trayId=Db::table('db_warehousing_sn')->where([
                        'tenant_id' => $user['tenant_id'],
                        'deleted_at' => 0,
                        'goods_id' => $sonInfo['goods_id'],
                        'sn' => $snArray[0],
                    ])->where('is_out','<>',1)->value('tray_id');
                    if(!empty($trayId))
                    $query->where('tray_id',$trayId);
                }
            })->find();
            foreach ($params['info'] as $key => $value) {
                $value['stock_id'] = $stockInfo['stock_id'];
                $value['tray_id'] = $stockInfo['tray_id'];
                $value['box_id'] = $stockInfo['box_id'];
                $value['slice_id'] = $stockInfo['slice_id'];
                $where['stock_id'] = $stockInfo['stock_id'];
                $where['tray_id'] = $stockInfo['tray_id'];
                $where['box_id'] = $stockInfo['box_id'];
                $where['slice_id'] = $stockInfo['slice_id'];
                // 替换中文逗号为英文逗号
                $value['sn'] = preg_replace('/，/', ',', $value['sn']);
                $value['sn'] = preg_replace('/,/', ',', $value['sn']);
                $value['sn'] = str_replace("\n", ",", $value['sn']);
                $snArr = [];
                if (!empty($value['sn'])) {
                    $snArr[] = $value['sn'];
                    if (!empty($value['sn'])) {
                        if (strpos($value['sn'], ',') !== false) {
                            $snArr = array_filter(explode(',', $value['sn']));
                        }
                        if (count($snArr) != $value['number']) {
                            return CatchResponse::fail('请填写与拣货数量相等的sn码！');
                        }
                    } else {
                        return CatchResponse::fail('请填写与拣货数量相等的sn码！');
                    }
                    DB::name('db_pick')
                        ->where([
                            'warehouse_out_id' => $params['warehouse_out_id'],
                            'warehouse_out_son_id' => $params['warehouse_out_son_id'],
                            'tenant_id' => $user['tenant_id']
                        ])->delete();
                    $snArrs = DB::name('db_pick')
                        ->where([
                            //'status'=>0,
                            'deleted_at' => 0,
                            'tenant_id' => $user['tenant_id'],
                        ])->whereIn('sn',$snArr)->column('sn');
                    if (!empty($snArrs)) {
                        $snArrs = implode(',',$snArrs);
                        return CatchResponse::fail('sn码：' . $snArrs . '已存在，请重新输入！');
                    }
                    foreach ($snArr as $sVal) {
                        //判断每一个库存最多捡货数量，前端如果没有控制的话，会有问题....
                        $pick_all = Db::table('db_pick')->where([
                            ['warehouse_out_son_id', '<>', $params['warehouse_out_son_id']],//除了这个订单外的
                            ['deleted_at', '=', 0],
                            ['status', '<>', 1],
                            ['stock_id', '=', $stockInfo['stock_id']],
                            ['tray_id', '=', $stockInfo['tray_id']],
                            ['box_id', '=', $stockInfo['box_id']],
                            ['slice_id', '=', $stockInfo['slice_id']],
                        ])->column('number');
                        $pick_counts = !empty($pick_all) ? array_sum($pick_all) : 0;

                        $pick_stock_where = [];
                        $pick_stock_where[] = ['tray_id', '=', $stockInfo['tray_id']];
                        $pick_stock_where[] = ['status', '<>', 1];
                        if (empty($stockInfo['box_id'])) {
                            $pick_stock_where[] = ['box_id', '=', 0];
                        } else {
                            $pick_stock_where[] = ['box_id', '=', $stockInfo['box_id']];
                        }
                        if (empty($stockInfo['slice_id'])) {
                            $pick_stock_where[] = ['slice_id', '=', 0];
                        } else {
                            $pick_stock_where[] = ['slice_id', '=', $stockInfo['slice_id']];
                        }

//                 $pick_stock_num = Db::table('db_stock')->where($pick_stock_where)->value('number');
                        $pick_stock_result = Db::table('db_stock')->where($pick_stock_where)
//                     ->field("SUM(Good_Qty + Hold_Qty + NG_Qty) as all_stock,Good_Qty,Hold_Qty,NG_Qty")->find();
                            ->field("Good_Qty,Hold_Qty,NG_Qty")->find();
                        $pick_stock_num = !empty($pick_stock_result) ? array_sum($pick_stock_result) : 0;

                        if (($max_pick_num = $pick_stock_num - $pick_counts) < $value['number']) {
                            throw new Exception("捡货数量，超出最大可捡货数量{$max_pick_num}" . "原库存：{$pick_stock_num}，已锁定{$pick_counts}");
                            Db::rollback();
                        }
                        ///判断单个库存数量，捡货数量是否合法  end------
                        //填写拣货数量
                        if (!empty($value['number'])) {

                            //拣货数据没有就添加
                            $value['pick_id'] = date('YmdHis') . mt_rand(10000, 99999) . $key;
                            $value['pick_no'] = $pick_no;
                            $value['creator_id'] = $request->user()->id;
                            $value['tenant_id'] = $user['tenant_id'];
                            $value['created_at'] = time();
                            $value['warehouse_out_id'] = $params['warehouse_out_id'];
                            $value['warehouse_out_son_id'] = $params['warehouse_out_son_id'];

                            //货的状态
                            if ($pick_stock_result['Good_Qty'] > 0) {
                                $value['stock_status'] = 'Good';
                            } elseif ($pick_stock_result['Hold_Qty'] > 0) {
                                $value['stock_status'] = 'Hold';
                            } elseif ($pick_stock_result['NG_Qty'] > 0) {
                                $value['stock_status'] = 'NG';
                            } else {
                                Db::rollback();
                                throw new Exception('库存错误，请刷新页面');
                            }

                            //2023 0424 保存库位
                            $value['config_id'] = Db::table('db_stock')
                                ->where('stock_id', $stockInfo['stock_id'])
                                ->value('config_id');
                            $pdata = $value;
                            $pdata['number'] = 1;
                            $pdata['sn'] = $sVal;
                            DB::name('db_pick')->insert($pdata);
                        }
                    }
                    Db::table('db_warehousing_sn')->where([
                        'goods_id' => $sonInfo['goods_id']
                    ])->whereIn('sn', $snArr)->update([
                        'is_out' => 2,
                        'updated_at' => time()
                    ]);
                }
            }
            $where_1 = [];
            $where_1[] = ['warehouse_out_son_id', '=', $params['warehouse_out_son_id']];
            $update_number = $this->pickModel->where($where_1)->sum('number');
            if ($update_number > $number) {
                Db::rollback();
                throw new Exception("捡货货累计数量{$update_number}，大于实际要出库数量{$number}，请解锁后在操作");
            }

            $this->pick_number($params['warehouse_out_son_id']);
            Db::commit();
            return CatchResponse::success('', '锁定成功');
        } catch (\Exception $exception) {
            Db::rollback();
            return CatchResponse::fail('锁定失败' . $exception->getMessage());
        }
    }

    /**
     *
     * @time 2022/01/26 17:31
     * @param $id
     * @return Response
     */
    public function read($id): Response
    {
        return CatchResponse::success($this->pickModel->findBy($id));
    }

    /**
     *
     * @time 2022/01/26 17:31
     * @param $id
     * @param Request $request
     * @return Response
     */
    public function update($id, Request $request): Response
    {
        return CatchResponse::success($this->pickModel->updateBy($id, $request->post()));
    }

    /**
     *
     * @time 2022/01/26 17:31
     * @return \think\response\Json
     * @throws \think\db\exception\DbException
     */
    public function delete(Request $request)
    {
        $params = $request->post();

        Db::startTrans();
        try {
            $where = [
                ['warehouse_out_son_id', '=', $params['warehouse_out_son_id']],//除了这个订单外的
                ['deleted_at', '=', 0],
                ['stock_id', 'in', $params['ids']]
            ];

            DB::name('db_pick')->where($where)->delete();

            $this->pick_number($params['warehouse_out_son_id']);
            Db::commit();
            return CatchResponse::success('', '删除成功');
        } catch (\Exception $exception) {
            Db::rollback();
            return CatchResponse::fail('删除失败');
        }
    }

    /**
     * 统计拣货数量
     * @time 2022/01/23 13:53
     * @param Request $request
     * @return string
     */
    public function pick_number($warehouse_out_son_id)
    {
        //统计拣货数量
        $number = DB::name('db_pick')
            ->where('warehouse_out_son_id', $warehouse_out_son_id)
            ->where('deleted_at', 0)
            ->sum('number');

        $info = DB::name('db_warehouse_out_son')
            ->where('warehouse_out_son_id', $warehouse_out_son_id)
            ->where('deleted_at', 0)
            ->update(['pick_number' => $number]);

        return $info;
    }
}